package com.txc.pay.alipayLife.socket;


import com.txc.openfeign.common.pay.vo.ResBaseVO;
import com.txc.common.utils.pay.ByteDataBuffer;
import com.txc.pay.alipayLife.service.AliPayLifeService;
import com.txc.pay.alipayLife.utils.ComposeUtil;
import com.txc.pay.alipayLife.utils.DeSplitUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import jakarta.net.ssl.KeyManagerFactory;
import jakarta.net.ssl.SSLContext;
import jakarta.net.ssl.SSLServerSocket;
import jakarta.net.ssl.TrustManagerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.KeyStore;
import java.util.Map;

/**
 * @ClassName: ServiceSocketConfig
 * @Description: 服务socket配置类
 * @Author: TXC
 * @Date: 2023-12-29 17:32
 **/
@Component
public class ServiceSocketConfig {

    @Resource
    AliPayLifeService aliPayLifeService;

    @Value(value = "${lifePay.lifeServerPort}")
    private int aliLifeServerPort;
    @Value(value = "${lifePay.serverPrivateKey}")
    private String serverPrivateKey;
    @Value(value = "${lifePay.serverKeyPassword}")
    private String serverKeyPassword;
    @Value(value = "${lifePay.trustKey}")
    private String trustKey;
    @Value(value = "${lifePay.trustKeyPassword}")
    private String trustKeyPassword;

    private static final Logger log = LoggerFactory.getLogger(ServiceSocketConfig.class);

    public static ServerSocket serverSocket = null;

    @Bean
    public void socketCreate() {
        serverSocket = createSSLServerSocket();
        log.info("socket服务端开启");
        Thread thread = new Thread(() -> {
            while (true){
                try {
                    Socket socket = serverSocket.accept();
                    log.info("接收到客户端socket - {}", socket.getRemoteSocketAddress());
                    handel(socket);
                } catch (IOException e) {
                    log.error("socket服务启动异常 - {}", e.getMessage());
                }
            }
        });
        thread.start();
    }

    private ServerSocket createSSLServerSocket(){
        try {
            SSLContext ctx = SSLContext.getInstance("SSL");
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
            KeyStore ks = KeyStore.getInstance("JKS");
            KeyStore tks = KeyStore.getInstance("JKS");
            ks.load(getResourceInputStream(serverPrivateKey), serverKeyPassword.toCharArray());
            tks.load(getResourceInputStream(trustKey), trustKeyPassword.toCharArray());
            kmf.init(ks, serverKeyPassword.toCharArray());
            tmf.init(tks);
            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
            SSLServerSocket serverSocket =  (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(aliLifeServerPort);
            serverSocket.setNeedClientAuth(true);
            return serverSocket;
        } catch (Exception e) {
            log.info("ssl 服务启动异常 - {}", e.getMessage());
        }
        return null;
    }

    public InputStream getResourceInputStream(String fileName) throws IOException {
        ClassPathResource classPathResource = new ClassPathResource(fileName);
        return classPathResource.getInputStream();
    }

    public void handel(Socket socket) throws IOException {
        try {
            byte[] buffer = new byte[10240];
            InputStream in = socket.getInputStream();
            in.read(buffer);
            ByteDataBuffer bdb = new ByteDataBuffer(buffer);
            Map<String, Object> params = DeSplitUtil.doCanProcess2Map(bdb);
            Map<String, Object> head = (Map<String, Object>) params.get("head");
            Map<String, Object> body = (Map<String, Object>) params.get("body");
            ResBaseVO resVo = aliPayLifeService.aliPayFallBack(head, body);
            OutputStream out = socket.getOutputStream();
            out.write(ComposeUtil.jsonToBytes(head, resVo));
            out.flush();
        } catch (Exception e) {
            log.info("支付宝生活缴费接收数据异常socket关闭 - {}", e.getMessage());
        }finally {
            if (socket != null) {
                socket.close();
                log.info("socket关闭");
            }
        }
    }

}
